﻿using System;
using System.Collections.Generic;
using System.Drawing;
using Dataweb.NShape.Advanced;
using Dataweb.NShape;
using System.ComponentModel;
using cz.zcu.PreSti.Components;
using System.Linq;
using System.Text;

namespace cz.zcu.PreSti.Shapes
{
    public class TextStimulusSymbol : StimulusSymbol
    {
        protected override void InitializeToDefault(IStyleSet styleSet)
        {
            base.InitializeToDefault(styleSet);
            Text = "Text";
        }

        public override void CopyFrom(Shape source) {
			base.CopyFrom(source);
		}

        public override int SettersCount
        {
            get { return 6; }
        }

        public override string GetTitleForSetter(int id)
        {
            string tmp = base.GetTitleForSetter(id);
            switch (id)
            {
                case 0: tmp = "Delay"; break;
                case 1: tmp = "Text"; break;
                case 2: tmp = "X Position"; break;
                case 3: tmp = "Y Position"; break;
                case 4: tmp = "Font Size"; break;
                case 5: tmp = "Rotation"; break;
            }
            return tmp;
        }

        public override Shape Clone()
        {
            Shape result = new TextStimulusSymbol(Type, (Template)null);
            result.CopyFrom(this);
            return result;
        }

        protected internal TextStimulusSymbol(ShapeType shapeType, Template template)
            : base(shapeType, template)
        {
        }

        #region ISymbol Members

        public override BaseComponent initializeComponent(IPresentation p)
        {
            TextStimulusModel model = (TextStimulusModel)this.ModelObject;
            TextStimulus stimulus = new TextStimulus(p);
            stimulus.Position = new Microsoft.Xna.Framework.Point(model.X, model.Y);
            stimulus.Text = model.Text;
            stimulus.Delay = model.Duration;
            stimulus.FontName = model.FontName.ElementAt(0);
            stimulus.FontSize = model.FontSize;
            stimulus.Color = model.Color;
            stimulus.Italics = model.Italics;
            stimulus.Bold = model.Bold;
            stimulus.Rotation = model.Rotation; 
            stimulus.Centred = model.Centred;
            stimulus.AlignmentHorizontal = model.AlignmentHorizontal;
            stimulus.AlignmentVertical = model.AlignmentVertical;

            //stimulus.initFont();
            return stimulus;
        }

        #endregion

        internal static Shape CreateInstance(ShapeType shapeType, Template template)
        {
            return new TextStimulusSymbol(shapeType, template);
        }

    }

    public class TextStimulusModel : ModelObjectBase
    {

        #region Fields

        private int duration = 5000;
        private string text = "text";
        private Point position = Point.Empty;
        private int fontSize = 16;
        private Microsoft.Xna.Framework.Color color = Microsoft.Xna.Framework.Color.White;
        private bool italics = false;
        private bool bold = false;
        private double rotation = 0;
        private bool centred = false;
        private char securityDomainName = 'A';
        private string alignmentHorizontal = "none";
        private string alignmentVertical = "none";


        private List<String> fontName = new List<string>()
        {
            TextStimulus.CHOOSER_MSG,
            TextStimulus.FontNames.Arial.ToString(),
            TextStimulus.FontNames.Georgia.ToString(),
            TextStimulus.FontNames.Segoe.ToString(),
            TextStimulus.FontNames.TimesNewRoman.ToString()
        };
        private const int PropertyIdDuration = 1;
        private const int PropertyIdPresText = 2;
        private const int PropertyIdX = 3;
        private const int PropertyIdY = 4;
        private const int PropertyIdFontName = 5;
        private const int PropertyIdFontSize = 6;
        private const int PropertyIdColor = 7;
        private const int PropertyIdItalics = 8;
        private const int PropertyIdBold = 9;
        private const int PropertyIdRotation = 10;
        private const int PropertyIdCentred = 11;
        private const int PropertyIdAlignmentHorizontal = 12;
        private const int PropertyIdAlignmentVertical = 13;

        #endregion

        #region properties

        [Category("Presentation")]
        [Description("Duration of the stimulus in miliseconds.")]
        [PropertyMappingId(PropertyIdDuration)]
        public virtual int Duration
        {
            get
            {
                return duration;
            }
            set
            {
                duration = value;
            }
        }

        [Category("Presentation")]
        [Description("Text of the stimulus.")]
        [PropertyMappingId(PropertyIdPresText)]
        public virtual string Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
            }
        }

        [Category("Presentation")]
        [Description("X-axis position of the stimulus. Condition: Horizontal statement - none")]
        [PropertyMappingId(PropertyIdX)]
        public virtual int X
        {
            get
            {
                return position.X;
            }
            set
            {
                position.X = value;
            }
        }

        [Category("Presentation")]
        [Description("Y-axis position of the stimulus. Condition: Vertical statement - none ")]
        [PropertyMappingId(PropertyIdY)]
        public virtual int Y
        {
            get
            {
                return position.Y;
            }
            set
            {
                position.Y = value;
            }
        }

        [Category("Presentation")]
        [Description("Font name - use \"...\" button and arrows to move chosen font type to the top.")]
        [Editor("System.Windows.Forms.Design.StringCollectionEditor",
        typeof(System.Drawing.Design.UITypeEditor))]
        [PropertyMappingId(PropertyIdFontName)]
        public virtual List<string> FontName
        {
            get
            {
                return fontName;
            }
            set
            {
                fontName = value;
            }
        }

        [Category("Presentation")]
        [Description("Font size.")]
        [PropertyMappingId(PropertyIdFontSize)]
        public virtual int FontSize
        {
            get
            {
                return fontSize;
            }
            set
            {
                fontSize = value;
            }
        }

        [Category("Presentation")]
        [Description("Font color. Define additive RGB(red, green, blue) color model.")]
        [PropertyMappingId(PropertyIdColor)]
        public virtual Microsoft.Xna.Framework.Color Color
        {
            get
            {
                return color;
            }
            set
            {
                color = value;
            }
        }

        [Category("Presentation")]
        [Description("Font italics style.")]
        [PropertyMappingId(PropertyIdItalics)]
        public virtual bool Italics
        {
            get
            {
                return italics;
            }
            set
            {
                italics = value;
            }
        }

        [Category("Presentation")]
        [Description("Font bold style.")]
        [PropertyMappingId(PropertyIdBold)]
        public virtual bool Bold
        {
            get
            {
                return bold;
            }
            set
            {
                bold = value;
            }
        }

        [Category("Presentation")]
        [Description("Font rotation in radians.")]
        [PropertyMappingId(PropertyIdRotation)]
        public virtual double Rotation
        {
            get
            {
                return rotation;
            }
            set
            {
                rotation = value;
            }
        }

        [Category("Presentation")]
        [Description("Centred.")]
        [PropertyMappingId(PropertyIdCentred)]
        public virtual bool Centred
        {
            get
            {
                return centred;
            }
            set
            {
                centred = value;
            }
        }

        [Category("Presentation")]
        [Description("Horizontal alignment (none, left, center, right).")]
        [PropertyMappingId(PropertyIdAlignmentHorizontal)]
        public string AlignmentHorizontal
        {
            get { return alignmentHorizontal; }
            set { alignmentHorizontal = value; }
        }

        [Category("Presentation")]
        [Description("Vertical alignment (none, top, center, bottom).")]
        [PropertyMappingId(PropertyIdAlignmentVertical)]
        public string AlignmentVertical
        {
            get { return alignmentVertical; }
            set { alignmentVertical = value; }
        }

        #endregion

        public static TextStimulusModel CreateInstance(ModelObjectType modelObjectType) {
			return new TextStimulusModel(modelObjectType);
		}


		protected internal TextStimulusModel(ModelObjectType modelObjectType)
			: base(modelObjectType)
        {
            this.terminalCount = 9;
		}


        protected internal TextStimulusModel(TextStimulusModel source)
			: base(source) {
            Duration = source.Duration;
            Text = source.Text;
            X = source.X;
            Y = source.Y;
            FontName = FontName;
            FontSize = source.FontSize;
            Color = source.Color;
            Italics = source.Italics;
            Bold = source.Bold;
            Rotation = source.Rotation;
            Centred = source.Centred;
            AlignmentHorizontal = source.alignmentHorizontal;
            AlignmentHorizontal = source.alignmentVertical;
            this.terminalCount = 9;
		}


		public override IModelObject Clone() {
            return new TextStimulusModel(this);
		}


		public override IEnumerable<MenuItemDef> GetMenuItemDefs() {
			throw new NotImplementedException();
		}


		public override void Connect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId) {
		}


		public override void Disconnect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId) {
		}

        public override char SecurityDomainName
        {
            get { return securityDomainName; }
            set
            {
                if (value < 'A' || value > 'Z')
                    throw new ArgumentOutOfRangeException("SecurityDomainName", "The domain qualifier has to be an upper case  ANSI letter (A-Z).");
                securityDomainName = value;
            }
        }


        #region IEntity Members

        public static new IEnumerable<EntityPropertyDefinition> GetPropertyDefinitions(int version)
        {
            foreach (EntityPropertyDefinition pi in ModelObjectBase.GetPropertyDefinitions(version))
                yield return pi;
            yield return new EntityFieldDefinition("Duration", typeof(int));
            yield return new EntityFieldDefinition("Text", typeof(string));
            yield return new EntityFieldDefinition("X", typeof(int));
            yield return new EntityFieldDefinition("Y", typeof(int));
            yield return new EntityFieldDefinition("FontName", typeof(List<string>));
            yield return new EntityFieldDefinition("FontSize", typeof(int));

            yield return new EntityFieldDefinition("ColorR", typeof(byte));
            yield return new EntityFieldDefinition("ColorG", typeof(byte));
            yield return new EntityFieldDefinition("ColorB", typeof(byte));

            yield return new EntityFieldDefinition("Italics", typeof(bool));
            yield return new EntityFieldDefinition("Bold", typeof(bool));
            yield return new EntityFieldDefinition("Rotation", typeof(double));
            yield return new EntityFieldDefinition("Centred", typeof(bool));

            yield return new EntityFieldDefinition("AlignmentHorizontal", typeof(string));
            yield return new EntityFieldDefinition("AlignmentVertical", typeof(string));
        }

        protected override void LoadFieldsCore(IRepositoryReader reader, int version)
        {
            base.LoadFieldsCore(reader, version);
            Duration = reader.ReadInt32();
            Text = reader.ReadString();
            X = reader.ReadInt32();
            Y = reader.ReadInt32();
            FontName = new List<string>(){reader.ReadString()};
            FontSize = reader.ReadInt32();

            byte rr = reader.ReadByte();
            byte gg = reader.ReadByte();
            byte bb = reader.ReadByte();
            Color = new Microsoft.Xna.Framework.Color(rr, gg, bb);   
        
            Italics = reader.ReadBool();
            Bold = reader.ReadBool();
            Rotation = reader.ReadFloat();
            Centred = reader.ReadBool();
            AlignmentHorizontal = reader.ReadString();
            AlignmentVertical = reader.ReadString();
        }

        protected override void SaveFieldsCore(IRepositoryWriter writer, int version)
        {
            base.SaveFieldsCore(writer, version);
            writer.WriteInt32(Duration);
            writer.WriteString(Text);
            writer.WriteInt32(X);
            writer.WriteInt32(Y);
            writer.WriteString(FontName.ElementAt(0));
            writer.WriteInt32(FontSize);

            writer.WriteByte(color.R);
            writer.WriteByte(color.G);
            writer.WriteByte(color.B);

            writer.WriteBool(Italics);
            writer.WriteBool(Bold);
            writer.WriteDouble(Rotation);
            writer.WriteBool(Centred);

            writer.WriteString(AlignmentHorizontal);
            writer.WriteString(AlignmentVertical);
        }

        #endregion
	}


}
